home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '88 / Proceedings '88 / Feldt Advanced Mac Programming / SCSI Manager / ssgSCSI.c < prev    next >
Encoding:
Text File  |  1988-06-16  |  7.2 KB  |  391 lines  |  [TEXT/KAHL]

  1. /* 
  2.         Copyright (c) 1987 by small systems guild
  3.         
  4.         small systems guild
  5.         PO box 2751
  6.         Ann Arbor, MI 48106
  7.         (313) 996-4238
  8.         
  9.         File:         ssgSCSI.c
  10.         Model:         LightSpeed C 2.11, Aztec C 1.06i
  11.         Target:     Macintosh Operating System
  12.         
  13. #include <quickdraw.h>
  14. #include "ssgSCSI.h"
  15.  
  16. struct SCSIInstr     cmdbuf;
  17. struct SCSIInstr     mbuf[3];
  18. Byte                tst[10];
  19. int                    sect,stat,msg;
  20. Byte                *cmp;
  21. long                wait,len;
  22. OSErr                err;
  23. int                    verbose = 0;
  24.  
  25. gSC_init()
  26. {
  27.     cmp = (unsigned char *)NewPtr((long)SIZE);
  28. }
  29.  
  30.  
  31. OSErr gSC_loadUnload(scuzzID)
  32. int        scuzzID;
  33. {
  34.     if (gSC_select(scuzzID) != noErr) {
  35.         return(-1);
  36.     }
  37.     tst[0] = 0x1B;
  38.     tst[1] = 0x01;                /* return immediately after command    */
  39.     tst[2] = 0x00;
  40.     tst[3] = 0x00;
  41.     tst[4] = 0x00;
  42.     tst[5] = 0x00;
  43.     gSC_cmd(tst);
  44. }
  45.  
  46. OSErr gSC_unitReady(scuzzID)
  47. int        scuzzID;
  48. {
  49.     if (gSC_select(scuzzID) != noErr) {
  50.         return(-1);
  51.     }
  52.     tst[0] = 0x00;
  53.     tst[1] = 0x00;
  54.     tst[2] = 0x00;
  55.     tst[3] = 0x00;
  56.     tst[4] = 0x00;
  57.     tst[5] = 0x00;
  58.     return(gSC_cmd(tst));
  59. }
  60.  
  61. OSErr gSC_reqSense(scuzzID)
  62. int        scuzzID;
  63. {
  64.     Byte    len;
  65.  
  66.     if (gSC_select(scuzzID) != noErr) {
  67.         return(-1);
  68.     }
  69.     gSC_CMD(0x03,NULL,NULL);
  70.     gSC_error(SCSIRead(gSC_TIB(cmp,13L,1L)));
  71.     gSC_finish();
  72.     if(verbose)
  73.         printf("request sense: %x\n",cmp[0]);    
  74.     return(stat);
  75. }
  76.  
  77. OSErr gSC_read(scuzzID,buf,block,sector,count)
  78. int        scuzzID;
  79. Byte     *buf;
  80. Int32    block;
  81. Int16    sector;
  82. UInt16    count;
  83. {
  84.     if (gSC_select(scuzzID) != noErr) {
  85.         return(-1);
  86.     }
  87.     gSC_CMD(0x08,(long)((block * 32) + sector),(long)count);
  88.     gSC_error(SCSIRead(gSC_TIB(buf,512L,(long)count)));
  89.     gSC_finish();
  90.     return(stat);
  91. }
  92.  
  93. OSErr gSC_write(scuzzID,buf,block,sector,count)
  94. int        scuzzID;
  95. Byte     *buf;
  96. Int32    block;
  97. Int16    sector;
  98. UInt16    count;
  99. {
  100.     if (gSC_select(scuzzID) != noErr) {
  101.         return(-1);
  102.     }
  103.     gSC_CMD(0x0A,(long)((block * 32) + sector),(long)count);
  104.     gSC_error(SCSIWrite(gSC_TIB(buf,512L,(long)count)));
  105.     gSC_finish();
  106.     return(stat);
  107. }
  108.  
  109. OSErr gSC_inquire(scuzzID)
  110. int        scuzzID;
  111. {
  112.     if (gSC_select(scuzzID) != noErr) {
  113.         return(-1);
  114.     }
  115.     gSC_CMD(0x12,NULL,NULL);
  116.     gSC_error(SCSIRead(gSC_TIB(cmp,36L,1L)));
  117.     gSC_finish();
  118.     if(verbose)
  119.         printf("inquiry: %s\n",&cmp[8]);    
  120.     return(stat);
  121. }
  122.  
  123. OSErr gSC_rdCapacity(scuzzID,buf)
  124. int        scuzzID;
  125. Byte    *buf;
  126. {
  127.     if (gSC_select(scuzzID) != noErr) {
  128.         return(-1);
  129.     }
  130.     gSC_CMD(0x25,NULL,NULL);
  131.     gSC_error(SCSIRead(gSC_TIB(buf,8L,1L)));
  132.     gSC_finish();
  133.     if(verbose)
  134.         printf("SCSI ID: %d address: %ld  size: %ld\n",scuzzID,*((long *)(&buf[0])),*((long *)(&buf[4])));    
  135.     return(stat);
  136. }
  137.  
  138. OSErr gSC_cmd(cmd)    /* handles 6 byte SCSI commands only    */
  139. Byte    *cmd;
  140. {
  141.     gSC_error(SCSICmd(cmd,(long)6));
  142.     return(gSC_finish());
  143. }    
  144.  
  145. OSErr gSC_6cmd(cmd)
  146. Byte    *cmd;
  147. {
  148.     gSC_error(SCSICmd(cmd,(long)6));
  149. }    
  150.  
  151. OSErr gSC_10cmd(cmd)
  152. Byte    *cmd;
  153. {
  154.     gSC_error(SCSICmd(cmd,(long)10));
  155. }    
  156.  
  157. Byte *gSC_TIB(buf,size,times)
  158. Byte    *buf;
  159. long    size,times;
  160. {
  161.     mbuf[0].scOpcode = scInc;
  162.     mbuf[0].scParam1 = (long)buf;
  163.     mbuf[0].scParam2 = (long)size;
  164.     mbuf[1].scOpcode = scLoop;
  165.     mbuf[1].scParam1 = -10L;
  166.     mbuf[1].scParam2 = (long)times;
  167.     mbuf[2].scOpcode = scStop;
  168.     mbuf[2].scParam1 = NULL;
  169.     mbuf[2].scParam2 = NULL;
  170.     return((Byte *)mbuf);
  171. }    
  172.  
  173. OSErr    gSC_CMD(cmdID,address,sectors)        /* create SCSI command block structure        */
  174. Byte        cmdID;
  175. long        address;
  176. long        sectors;
  177. {
  178. long    cmdBytes = 6L;
  179.  
  180.     tst[0] = 0x00;
  181.     tst[1] = 0x00;
  182.     tst[2] = 0x00;
  183.     tst[3] = 0x00;
  184.     tst[4] = 0x00;
  185.     tst[5] = 0x00;
  186.     tst[6] = 0x00;
  187.     tst[7] = 0x00;
  188.     tst[8] = 0x00;
  189.     tst[9] = 0x00;
  190.  
  191.     switch (cmdID) {
  192.         case 0x03:                /* SCSI request sense    */
  193.             tst[0] = 0x03;
  194.             tst[4] = 0x0D;        /* tell device that 13 bytes are available for data    */
  195.             break;
  196.         case 0x08:                /* SCSI read request    */
  197.             tst[0] = 0x08;
  198.             tst[2] = (UInt16)address >> 8;
  199.             tst[3] = (UInt16)address & 0xFF;
  200.             tst[4] = (Byte)sectors;
  201.             break;
  202.         case 0x0A:                /*  SCSI write request    */
  203.             tst[0] = 0x0A;
  204.             tst[2] = (UInt16)address >> 8;
  205.             tst[3] = (UInt16)address & 0xFF;
  206.             tst[4] = (Byte)sectors;
  207.             break;
  208.         case 0x12:                /*  SCSI inquiry    */
  209.             tst[0] = 0x12;
  210.             tst[4] = 0x24;        /* tell device that 36 bytes are available for inquery    */
  211.             break;
  212.         case 0x25:                /* Read capacity SCSI comamnd    */
  213.             tst[0] = 0x25;        /* Read capacity opcode    */
  214.             tst[1] = 0x00;        /* ask for last logical block address and block length */
  215.             cmdBytes = 10L;
  216.             break;
  217.         case 0x2C:                /* Read tape header - Irwin specific command    */
  218.             tst[0] = 0x2C;
  219.             tst[7] = 0x04;        /* set transfer size to 1024    */
  220.             cmdBytes = 10L;
  221.             break;
  222.         case 0x2D:                /* Write tape header - Irwin specific command    */
  223.             tst[0] = 0x2D;
  224.             tst[7] = 0x04;        /* set transfer size to 1024    */
  225.             cmdBytes = 10L;
  226.             break;
  227.     }
  228.     return(gSC_error(SCSICmd(tst,cmdBytes)));
  229. }
  230.  
  231. OSErr gSC_select(ID)
  232. int        ID;
  233. {
  234.     gSC_error(err = SCSIGet());
  235.     if (err != noErr)
  236.         return(-1);
  237.  
  238.     gSC_error(err = SCSISelect(ID));
  239.     if (err != noErr) {
  240.         return(-1);
  241.     }
  242.     return(noErr);
  243. }
  244.  
  245. OSErr gSC_error(errNum)
  246. OSErr    errNum;
  247. {
  248.     if (verbose) {
  249.         switch(errNum) {
  250.             case noErr:
  251. /*                printf("SCSI cmd: OK\n");*/
  252.                 break;
  253.             case -1:
  254.                 printf("SCSI error: Internal select/build error\n");
  255.                 break;
  256.             case scCommErr:
  257.                 printf("SCSI error: Breakdown in SCSI protocols\n");
  258.                 break;
  259.             case scPhaseErr:
  260.                 printf("SCSI error: Phase error\n");
  261.                 break;
  262.             case scBadParmsErr:
  263.                 printf("SCSI error: Unrecognized instruction\n");
  264.                 break;
  265.             case scCompareErr:
  266.                 printf("SCSI error: Data comparison error during compare\n");
  267.                 break;
  268.             default:
  269.                 printf("SCSI error: Unknown error number %d\n",errNum);
  270.                 break;
  271.         }
  272.     }
  273. }
  274.  
  275. OSErr gSC_finish()
  276. {
  277.     wait = TIME_OUT;
  278.     gSC_error(SCSIComplete(&stat,&msg,wait));
  279.     if (verbose)
  280.         printf("status: %d   message: %d\n",stat,msg);
  281.     return(stat);    
  282. }
  283.  
  284. gSC_scan(driveList,maxDrives)
  285. int    *driveList;
  286. int    maxDrives;
  287. {
  288.     int        i,j;
  289.  
  290.     for (j = 0;j < 2;j++) {
  291.         for (i = 0;i < maxDrives;i++) {
  292.             driveList[i] = 0;
  293.             if (i == 7) {
  294.                 driveList[i] = 3;
  295.                 continue;
  296.             }
  297.                 
  298.             if (err = gSC_unitReady(i) != noErr) {
  299.                 if (err != 2) {
  300.                     driveList[i] = 0;
  301.                     continue;
  302.                 }
  303.                 else
  304.                     driveList[i] = 4;
  305.             }
  306.     
  307.             if (gSC_inquire(i) != noErr) {
  308.                 driveList[i] = 0;
  309.                 continue;
  310.             }
  311.             else {
  312.                 if (cmp[8] == 'I' && cmp[9] == 'R')
  313.                     driveList[i] = 2;
  314.                 else
  315.                     driveList[i] = 1;
  316.             }
  317.         }
  318.     }
  319. }
  320.  
  321. dump_drvList(driveList,maxDrives)
  322. int    *driveList;
  323. int    maxDrives;
  324. {
  325.     int        i;
  326.  
  327.     printf("SCSI bus device available list\n",i);
  328.     for (i = 0;i < maxDrives;i++) {
  329.         switch (driveList[i]) {
  330.             case 0:
  331.                 printf("SCSI device %d is not available\n",i);
  332.                 break;
  333.             case 1:
  334.                 printf("SCSI device %d is a hard disk\n",i);
  335.                 break;
  336.             case 2:
  337.                 printf("SCSI device %d is an Irwin tape drive\n",i);
  338.                 break;
  339.             case 3:
  340.                 printf("SCSI device %d is an Apple Macintosh\n",i);
  341.                 break;
  342.             case 4:
  343.                 printf("SCSI device %d is present but not ready\n",i);
  344.                 break;
  345.         }
  346.     }
  347. }
  348.  
  349. int gSC_findTape(maxDrives)
  350. int    maxDrives;
  351. {
  352.     int        i,j;
  353.     int        driveList[8], drive = -1;    
  354.  
  355.     for (j = 0;j < 2;j++) {
  356.         for (i = 0;i < maxDrives;i++) {
  357.             driveList[i] = 0;
  358.             if (i == 7) {
  359.                 driveList[i] = 3;
  360.                 continue;
  361.             }
  362.                 
  363.             if (err = gSC_unitReady(i) != noErr) {
  364.                 if (err != 2) {
  365.                     driveList[i] = 0;
  366.                     continue;
  367.                 }
  368.                 else
  369.                     driveList[i] = 4;
  370.             }
  371.     
  372.             if (gSC_inquire(i) != noErr) {
  373.                 driveList[i] = 0;
  374.                 continue;
  375.             }
  376.             else {
  377.                 if (cmp[8] == 'I' && cmp[9] == 'R')
  378.                     driveList[i] = 2;
  379.                 else
  380.                     driveList[i] = 1;
  381.             }
  382.         }
  383.     }
  384.     for (i = 0;i < maxDrives;i++) {
  385.         if (driveList[i] == 2)
  386.             drive = i;
  387.     }
  388.     return(drive);
  389. }
  390.  
  391.